#include "StdAfx.h"
#include "Nest.h"



Nest::Nest(ID id, unsigned int machines, unsigned int bufferSize,Communicator & com,
			Parameters * distribution, BufferType * bufferType ) :
	buffer(bufferSize,bufferType,com), Actor(com), distribution(distribution), id(id)
{
	for( unsigned int i = 0; i<machines; i++ ){
		this->machines.push_back(new Machine(com,id,this->machines.size(),distribution));
	}	
}



Nest::~Nest(void)
{
}

vector<Machine *> Nest::getMachines()
{
	return machines;
}

TaskBuffer *Nest::getBuffer()
{
	return &buffer;
}

std::string Nest::toString()
{
	int w = 0;
	for (size_t i = 0; i<machines.size() ;i++){
		if(!machines[i]->isEmpty()){
			w++;
		}
	}
	ostringstream str;
	str << "B:"<<buffer.toString() << " \t| M:" << w << "/" << machines.size();
	return  str.str();
}

void Nest::tick()
{
	for (size_t i = 0; i<machines.size(); i++){
		machines[i]->tick();
	}
	buffer.tick();
}

bool Nest::hasPlace()
{
	return buffer.hasPlace();
}

bool Nest::addTask( Task * task )
{
	if(buffer.addTask(task)){
		for (size_t i = 0; i<machines.size() && !buffer.isEmpty(); i++){
			if(machines[i]->isEmpty()){
				machines[i]->assignTask(buffer.popTask());
			}
		}
		return true;
	} else {
		return false;
	}
}

bool Nest::returnTask(ID machineID, Task **out_task)
{
	bool freeSlot = machines[machineID]->returnTask(out_task);
	if (freeSlot && !buffer.isEmpty())
	{
		machines[machineID]->assignTask(buffer.popTask());
	}
	return freeSlot;
}

Task* Nest::getTask( ID machine )
{
	return machines[machine]->currentTask;
}

bool Nest::hasFinishedTaskFor(ID nest, ID & out_machine )
{
	for (out_machine = 0; out_machine<machines.size(); out_machine++)
	{
		if(machines[out_machine]->hasFinished() && machines[out_machine]->currentTask->target == nest){
			return true;
		}
	}
	return false;
}

